package com.lagou.rpcconsumer;

import com.lagou.service.IUserService;
import com.lagou.service.JSONSerializer;
import com.lagou.service.RpcEncoder;
import com.lagou.service.RpcRequest;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author zhangxuyuan
 * @version 1.0
 * @date 2020/11/24
 */
@Configuration
public class BootStrapConfig {

//    @Autowired
//    UserClientHandler userClientHandler;

    @Autowired
    ProviderService providerService;

    private static ExecutorService executorService =
        Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

//    @Bean
//    public Bootstrap bootstrap()
//    {
//        //2)创建连接池对象
//        EventLoopGroup group = new NioEventLoopGroup();
//        //3)创建客户端的引导对象
//        Bootstrap bootstrap =  new Bootstrap();
//        //4)配置启动引导对象
//        bootstrap.group(group)
//            //设置通道为NIO
//            .channel(NioSocketChannel.class)
//            //设置请求协议为TCP
//            .option(ChannelOption.TCP_NODELAY,true)
//            //监听channel 并初始化
//            .handler(new ChannelInitializer<SocketChannel>() {
//                protected void initChannel(SocketChannel socketChannel) throws Exception {
//                    //获取ChannelPipeline
//                    ChannelPipeline pipeline = socketChannel.pipeline();
//                    //设置编码
//                    pipeline.addLast(new RpcEncoder(RpcRequest.class,new JSONSerializer()));
//                    pipeline.addLast(new StringDecoder());
//                    //添加自定义事件处理器
//                    pipeline.addLast(userClientHandler);
//                }
//            });
//
//        //5)连接服务端
//        bootstrap.connect("127.0.0.1",8999);
//        return bootstrap;
//    }


    @Bean
    public IUserService iUserService()
    {
        Object proxy = this.createProxy(IUserService.class);
        return (IUserService)proxy;
    }


    //4.编写一个方法,使用JDK的动态代理创建对象
    public Object createProxy(Class<?> serviceClass){
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
            new Class[]{serviceClass}, new InvocationHandler() {
            @Override
                public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                    //将调用信息封装进rpcRequest
                    RpcRequest rpcRequest=new RpcRequest();
                    rpcRequest.setClassName(method.getDeclaringClass().getName());
                    rpcRequest.setMethodName(method.getName());
                    rpcRequest.setParameterTypes(method.getParameterTypes());
                    rpcRequest.setParameters(objects);
                UserClientHandler handler = providerService.setParam(rpcRequest);

                //3).使用线程池,开启一个线程处理处理call() 写操作,并返回结果
                    Object result;

                    result = executorService.submit(handler).get();

                    //4)return 结果
                    return result;
                }
            });
    }

}
